package com.ultimatech.wxservice.web;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.ultimatech.wxservice.web.exception.MyExceptionHandler;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
import org.springframework.orm.hibernate4.support.OpenSessionInViewFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import javax.servlet.DispatcherType;
import java.util.Properties;

/**
 * Created by zhangleping on 16/10/17.
 */
@SpringBootApplication
@ComponentScan(basePackages = {"com.ultimatech.wxservice"})
@ImportResource("classpath*:conf/*-beans.xml")
public class WxserviceSvrApp extends SpringBootServletInitializer implements EmbeddedServletContainerCustomizer {

    private static Logger logger = LoggerFactory.getLogger(WxserviceSvrApp.class);

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

    //    @Bean
//    public FilterRegistrationBean encodingFilter() {
//        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
//        filterRegistration.setFilter(new CharacterEncodingFilter("utf-8",true));
//        filterRegistration.setEnabled(true);
//        filterRegistration.addUrlPatterns("/*");
//        filterRegistration.setOrder(0);
//        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
//        return filterRegistration;
//    }
//
//    @Bean
//    public FilterRegistrationBean hiddenHttpMethodFilter() {
//        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
//        filterRegistration.setFilter(new MyHiddenHttpMethodFilter());
//        filterRegistration.setEnabled(true);
//        filterRegistration.addUrlPatterns("/*");
//        filterRegistration.setOrder(1);
//        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
//        return filterRegistration;
//    }

    @Bean
    public FilterRegistrationBean opensessionFilter() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new OpenSessionInViewFilter());
        filterRegistration.addInitParameter("singleSession", "false");
        filterRegistration.setEnabled(true);
        filterRegistration.addUrlPatterns("/*");
        filterRegistration.setOrder(2);
        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
        filterRegistration.setAsyncSupported(true);
        return filterRegistration;
    }

//    @Bean(name = "shiroFilterBean")
//    @Resource
//    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager,
//                                                            @Qualifier("filterChainDefinitions") Ini.Section filterChainDefinitionMap) throws Exception {
//        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//        shiroFilterFactoryBean
//                .setSecurityManager(securityManager);
//        shiroFilterFactoryBean.setLoginUrl("/login");
//        shiroFilterFactoryBean.setSuccessUrl("/user");
//        shiroFilterFactoryBean.setUnauthorizedUrl("/403.html");
//        shiroFilterFactoryBean
//                .setFilterChainDefinitionMap(filterChainDefinitionMap);
//        RememberAuthenticationFilter formAuthenticationFilter = new RememberAuthenticationFilter();
//        Map<String, Filter> map = new HashMap<String, Filter>();
//        map.put("authc", formAuthenticationFilter);
//        shiroFilterFactoryBean.setFilters(map);
//        return shiroFilterFactoryBean;
//    }

    @Bean
    public FilterRegistrationBean shiroFilterr() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilterBean"));
        filterRegistration.setEnabled(true);
        filterRegistration.addUrlPatterns("/*");
        filterRegistration.setOrder(3);
        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
        filterRegistration.setAsyncSupported(true);
        return filterRegistration;
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public MyExceptionHandler simpleMappingExceptionResolver() {
        MyExceptionHandler resolver = new MyExceptionHandler();
        Properties map = new Properties();
        map.put("java.lang.Throwable", "500");
        resolver.setExceptionMappings(map);
        return resolver;
    }

//    @Bean
//    public ServletContextInitializer initializer(@Value("${mq.url}") final String mqUrl) {
//        return new ServletContextInitializer() {
//
//            @Override
//            public void onStartup(ServletContext servletContext) throws ServletException {
//                servletContext.setInitParameter("org.apache.activemq.brokerURL", mqUrl);
//                servletContext.setInitParameter("org.apache.activemq.embeddedBroker", "false");
//            }
//        };
//    }

    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }


    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(WxserviceSvrApp.class);
    }

    public static void main(String[] args) {
        logger.info("应用启动");
        ConfigurableApplicationContext ctx = SpringApplication.run(WxserviceSvrApp.class, args);

    }


    public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {
//        configurableEmbeddedServletContainer.setPort(Integer.valueOf(conf.getProperty("server.port")));
//        configurableEmbeddedServletContainer.setContextPath(conf.getProperty("server.contextPath"));
    }
}
